﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Text;
using Utility.Data;
using Utility.UI;

/// <summary>
/// 代码生成类
/// </summary>
public class BulidHelper
{
    private VelocityHelper vh = new VelocityHelper();
    private const string TemplateModel = "Model.vm";    //模板文件
    private const string TemplateBll = "Bll.vm";
    private const string TemplateIBll = "IBll.vm";

    #region 属性

    /// <summary>表主键</summary>
    public string TablelId { get; set; }
    /// <summary>数据库名</summary>
    public string DBName { get; set; }
    /// <summary>表名</summary>
    public string TableName { get; set; }
    /// <summary>表说明</summary>
    public string TableRemark { get; set; }
    /// <summary>列信息</summary>
    public string Communs { get; set; }
    /// <summary>显示列数</summary>
    public string CommunNum { get; set; }
    /// <summary>数据库链接</summary>
    public string ConnectionString { get; set; }
    #endregion

    #region 构造

    public BulidHelper()
    {
        if (String.IsNullOrEmpty(ConnectionString))
            return;
    }
    public BulidHelper(string table, string tableId)
    {
        this.TablelId = tableId;
    }
    #endregion

    #region 生成Aspx页面
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public string GetFormAspx()
    {
        string result = "";
        if (String.IsNullOrEmpty(CommunNum)) CommunNum = "1";
        //PAGE_TITLE COLUMN_NUM:每行列数 $COLS:所有列信息 COLUMN_INFO: FOOTER
        GetPublicPub(ref vh);

        StringBuilder sb_aspx = new StringBuilder();
        if (!String.IsNullOrEmpty(Communs))
        {
            int index = 1;
            int num = Int32.Parse(CommunNum);
            foreach (string item in Communs.Split('$'))
            {
                if (item.Length == 0)
                    continue;

                Hashtable ht = HashtableHelper.KeysToHashtable(item);
                string validator = ht["Validator"].ToString();
                int n = 0;
                string maxlength = "";//最大输入长度
                string ControlType = ht["Type"].ToString();
                if (validator != "")
                    validator = "datacol=\"yes\" err=\"" + ht["Remark"].ToString() + "\" checkexpession=\"" + validator + "\"";

                if (Int32.TryParse(ht["Length"].ToString(), out n))
                    maxlength = "maxlength=\"" + ht["Length"].ToString() + "\"";

                if ((index - 1) % num == 0)
                    sb_aspx.Append("    <tr>\r\n");

                sb_aspx.Append("            <th>" + ht["Remark"].ToString() + "：</th>\r\n");
                sb_aspx.Append("            <td>\r\n");
                switch (ControlType)
                {
                    #region 控件类型

                    case "1"://1 - 文本框
                        sb_aspx.Append("                  <input id=\"" + ht["Column"].ToString() + "\" " + maxlength + " runat=\"server\" type=\"text\"  " + validator + " class=\"txt\" style=\"width: " + ht["MaxLength"].ToString() + "\" />\r\n");
                        break;
                    case "2"://2 - 下拉框
                        sb_aspx.Append("                  <select id=\"" + ht["Column"].ToString() + "\" runat=\"server\" class=\"select\" style=\"width: " + ht["MaxLength"] + "\" " + validator + "></select>\r\n");
                        break;
                    case "3"://3 - 日期框
                        sb_aspx.Append("                  <input id=\"" + ht["Column"].ToString() + "\" " + maxlength + " onfocus=\"WdatePicker()\" class=\"txt\" runat=\"server\" type=\"text\" " + validator + " style=\"width: " + ht["MaxLength"].ToString() + "\" />\r\n");
                        break;
                    case "4"://4 - 标签
                        sb_aspx.Append("                  <label id=\"" + ht["Column"].ToString() + "\"/>\r\n");
                        break;
                    case "5"://5 - 文本区
                        sb_aspx.Append("                  <textarea id=\"" + ht["Column"].ToString() + "\"  " + maxlength + " runat=\"server\" class=\"txtArea\" type=\"text\" " + validator + "></textarea>\r\n");
                        break;
                    case "6"://6 - 复选框
                        sb_aspx.Append("                  <span class=\"item\">\r\n");
                        sb_aspx.Append("                  <input id=\"" + ht["Column"].ToString() + "\" type=\"checkbox\" runat=\"server\" checked=\"checked\" style=\"vertical-align: middle;\" />\r\n");
                        sb_aspx.Append("                  <label for=\"" + ht["Column"].ToString() + "\" style=\"vertical-align: middle;\">" + ht["Remark"].ToString() + "</label>\r\n");
                        //sb_aspx.Append("                  &nbsp;&nbsp;\r\n");
                        sb_aspx.Append("                  </span>\r\n");
                        break;
                    default:
                        break;
                    #endregion
                }
                sb_aspx.Append("            </td>\r\n");
                if (index % num == 0 || index == num)
                {
                    //index = 1;
                    sb_aspx.Append("     </tr>\r\n");
                }
                index++;
            }
        }
        vh.Put("COLUMN_INFO", sb_aspx.ToString());
        result = vh.Display("Form.vm");
        return result;
    }
    #endregion

    #region 生成PageList页面
    /// <summary>
    /// 
    /// </summary>
    /// <param name="isPage">是否分页</param>
    /// <returns></returns>
    public string GetPageListAspx(bool isPage)
    {
        GetPublicPub(ref vh);

        StringBuilder sb_aspx = new StringBuilder();
        string fields = "";
        if (!String.IsNullOrEmpty(Communs))
        {
            Hashtable ht = null;
            foreach (string item in Communs.Split('$'))
            {
                if (item.Length == 0)
                    continue;

                ht = HashtableHelper.KeysToHashtable(item);
                fields += "\"" + ht["Column"].ToString() + "\",";
                sb_aspx.Append("{ title:\"" + ht["Column"].ToString() + "\", width: 100, align: \"center\"" + (ht["Enabled"] == "on" ? ",hidden:true" : "") + " },\r\n");
            }
            if (fields.Length > 0)
                fields.Remove(fields.Length - 1);

            vh.Put("FIELDS", fields);
            vh.Put("COLM", sb_aspx.Remove(sb_aspx.Length - 5, 5).ToString());
        }
        return vh.Display(isPage ? "PageList.vm" : "NoPageList.vm");
    }
    #endregion

    #region 生成PageList.cs页面
    /// <summary>
    /// 
    /// </summary>
    /// <param name="isPage">是否分页</param>
    /// <returns></returns>
    public string GetPageListAspx_CS(bool isPage)
    {
        GetPublicPub(ref vh);

        return vh.Display(isPage ? "PageList_cs.vm" : "NoPageList_cs.vm");
    }
    #endregion

    #region 生成Aspx.cs
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public string GetAspx_CS()
    {
        GetPublicPub(ref vh);
        return vh.Display("Form_cs.vm");
    }
    #endregion

    #region 生成后台代码
    public string GetBehindCode(string type)
    {
        if (String.IsNullOrEmpty(ConnectionString))
            return "";

        GetPublicPub(ref vh);

        string result = "";
        if (type == "model")
            result = GetModel();

        if (type == "bll")
            result = GetBll();

        if (type == "ibll")
            result = GetIBll();

        return result;
    }


    /// <summary>
    /// Model 类
    /// </summary>
    /// <returns></returns>
    private string GetModel()
    {
        ColumnInfo[] cloumnArr = GetColumns();
        StringBuilder sb = new StringBuilder();
        foreach (ColumnInfo m in cloumnArr)
        {
            sb.Append("         /// <summary>\r\n");
            sb.Append("         ///").Append(m.Remark).Append("\r\n");
            sb.Append("         ///</summary>\r\n");

            sb.Append("         public " + FindModelType(m.Type) + " " + m.Name + "{ get; set; }\r\n");
        }
        vh.Put("MAIN_CODE", sb.ToString());
        return vh.Display(TemplateModel);
    }
    /// <summary>
    /// 获取数据表列信息
    /// </summary>
    /// <returns></returns>
    private ColumnInfo[] GetColumns()
    {
        ColumnInfo[] cloumnArr;
        using (DataTable dt = DBHelper.GetTableColumns(DBName, TableName, ConnectionString))
        {
            if (dt == null || dt.Rows.Count == 0)
                return new ColumnInfo[1];

            cloumnArr = new ColumnInfo[dt.Rows.Count];
            int i = 0;
            foreach (DataRow dr in dt.Rows)
            {
                ColumnInfo column = new ColumnInfo();
                column.Name = dr["column"].ToString();
                column.Type = dr["datatype"].ToString();
                column.Length = Convert.ToInt32(dr["length"].ToString());
                column.IsNull = dr["isnullable"].ToString() == "√" ? true : false;
                column.IsKey = dr["key"].ToString() == "√" ? true : false;
                column.Remark = dr["remark"].ToString();
                //cloumnInfo.IsIdentity = dr["column"].ToString();

                cloumnArr[i] = column;
                i++;
            }
        }
        return cloumnArr;
    }
    /// <summary>
    /// IBll 类
    /// </summary>
    /// <returns></returns>
    private string GetIBll()
    {
        return vh.Display(TemplateIBll);
    }
    /// <summary>
    /// Bll 类
    /// </summary>
    /// <returns></returns>
    private string GetBll()
    {
        return vh.Display(TemplateBll);
    }
    #endregion

    #region 返回C#实体数据类型
    public string FindModelType(string name)
    {
        string result = "";
        switch (name)
        {
            case "int":
            case "smallint":
                result = "int?";
                break;
            case "tinyint":
                result = "byte";
                break;
            case "numeric":
            case "real":
                result = "Single";
                break;
            case "bit":
                result = "bool";
                break;
            case "char":
            case "varchar":
            case "nchar":
            case "nvarchar":
            case "ntext":
                result = "string";
                break;
            case "datetime":
            case "smalldatetime":
                result = "DateTime?";
                break;
            case "money":
            case "smallmoney":
                result = "double";
                break;
            case "float":
            case "decimal":
                result = name;
                break;
            default:
                result = "string";
                break;
        }
        return result;
    }
    #endregion

    #region 返回C#数据类型
    public string FindType(string name)
    {
        if (name == "int" || name == "smallint")
        {
            return "Convert.ToInt32(";
        }
        else if (name == "tinyint")
        {
            return "Convert.ToByte(";
        }
        else if (name == "numeric" || name == "real" || name == "float")
        {
            return "Convert.ToSingle(";
        }
        else if (name == "decimal")
        {
            return "Convert.ToDecimal(";
        }
        else if (name == "char" || name == "varchar" || name == "text" || name == "nchar" || name == "nvarchar" || name == "ntext")
        {
            return ".ToString()";
        }
        else if (name == "bit")
        {
            return "Convert.ToBoolean(";
        }
        else if (name == "datetime" || name == "smalldatetime")
        {
            return "Convert.ToDateTime(";
        }
        else if (name == "money" || name == "smallmoney")
        {
            return "Convert.ToDouble(";
        }
        else
        {
            return ".ToString()";
        }
    }
    #endregion

    /// <summary>
    /// 加载公共变量
    /// </summary>
    /// <param name="vh"></param>
    private void GetPublicPub(ref VelocityHelper vh)
    {
        if (TablelId == null) TablelId = "";
        vh = new VelocityHelper();

        vh.Init(@"/Template");                      //初始化
        vh.Put("TABLE_NAME", TableName);            //表名
        vh.Put("TABLE_ID", TablelId);               //表主键
        vh.Put("CREATE_DATE", DateTime.Now);        //创建日期
        vh.Put("TABLE_REMARK", TableRemark);        //表说明

        vh.Put("EMAIL", Utility.Config.ConfigHelper.GetAppSettings("EMAIL"));    //Email
        vh.Put("AUTHOR", Utility.Config.ConfigHelper.GetAppSettings("AUTHOR"));  //作者
        vh.Put("COMPANY", Utility.Config.ConfigHelper.GetAppSettings("Company"));//公司
        vh.Put("FOOTER", "/UserControl/footer.htm");

        //命名空间
        vh.Put("IBLL_SPACE", Utility.Config.ConfigHelper.GetAppSettings("IBLL_SPACE"));
        vh.Put("BLL_SPACE", Utility.Config.ConfigHelper.GetAppSettings("BLL_SPACE"));
        vh.Put("MODEL_SPACE", Utility.Config.ConfigHelper.GetAppSettings("MODEL_SPACE"));
        vh.Put("WEB_SPACE", Utility.Config.ConfigHelper.GetAppSettings("WEB_SPACE"));
    }
}